﻿package com.vinyl.app
{
	import flash.display.MovieClip;
	import flash.events.*;
	import flash.utils.*;
	
	import com.vinyl.debug.*;
	
	/**
	 * The Application class is Document class.
	 * <p/>
	 * can includes all function in the commandQueue Array class.
	 * <p/>
	 * and function will execute in regular sequence.
	 * <p/>
	 */
	public class Application extends MovieClip
	{	
		//현재 실행중인 펑션
		private var _f:Function;
		private var _id:Number;
		
		//커멘드 큐
		private var _commandQueue = new Array();
		
		public var log:String;
		
		public function Application()
		{
			trace( "initialize" );
			addEventListener( Event.ENTER_FRAME, executeEvent );
		}
		
		/**
		 * 커맨드 큐 추가
		 */
		public function addQueueEvent( $owner, $type, $event, $params, $delay:Number = 0 ):void
		{
			//if ( !( root as Object ).mouseEnabled ) return;
			_commandQueue.push( { owner: $owner, type: $type, event: $event, params: $params, time: $delay } );
		}
		
		/**
		 * 커맨드 큐 실행
		 */
		private function executeEvent( $e:Event ):void
		{
			var len = _commandQueue.length;
			
			if (len > 0 )
			{
				for ( var i:uint = 0; i < 1; i++ )  //커맨드 큐 동시 실행의 갯수( i ) 를 설정한다.
				{
					if( _commandQueue.length == 0 ) continue;
					
					if( _commandQueue[0].time > 0 )
					{
						removeEventListener( Event.ENTER_FRAME, executeEvent );
						_id = setTimeout( function(){ addEventListener( Event.ENTER_FRAME, executeEvent ); }, _commandQueue[0].time );
						_commandQueue[0].time = 0;
						
						return;
					}
					
					var que = _commandQueue[0];
					var owner = ( _commandQueue[0].owner as Object );
					
					if ( typeof( que.event ) == "string" )
					{
						if ( owner[que.event] == _f ) {  continue; }
						
						_f = owner[que.event];
						owner[que.event].apply( owner, _commandQueue[0].params );
					}
					else
					{
						if ( que.event == _f ) {  continue; }
						
						_f = que.event;
						que.event.apply( owner, _commandQueue[0].params );	
					}
					
					trace( "EXE "  + que.event + " : " +  _commandQueue[0].params + " : remains commandQueue: " + _commandQueue.length );
					var date:Date = new Date();
					var d = date.hours+":"+date.minutes+":"+date.seconds +"  "+  date.month+","+ date.day;
					log = d + " : EXE "  + que.event + " : " +  _commandQueue[0].params + " : remains commandQueue: " + _commandQueue.length + "\n";
					
					//log = Debug.toString( que ) + "\n";
					dispatchEvent( new Event( "log" ) );
					
					if( que.type ) { _commandQueue.shift(); _f = function(){} };
				}
			}
		}
		
		/**
		 * 커맨드 큐 펑션 제거
		 */
		public function completeCall($f): void
		{
			if( _f == $f )
			{
				//trace( commandQueue[0].event + ": complete command" )
				_commandQueue.shift();
			}
		}
		
		public function reset(): void
		{
			pause();
			_commandQueue = null;
			_commandQueue = new Array();
			resume();
		}
		
		public function destory(): void
		{	
			removeEventListener( Event.ENTER_FRAME, executeEvent );
			_commandQueue = null;
			_f = null;
		}
		
		public function resume(): void
		{
			trace( "app resume" );
			if( !hasEventListener( Event.ENTER_FRAME ) ) addEventListener( Event.ENTER_FRAME, executeEvent ) 
		}	
		
		public function pause(): void
		{
			trace( "app pause" );
			//시간 대기중일때는 어떻게?
			if( _id ) clearTimeout( _id );
			if( hasEventListener( Event.ENTER_FRAME ) ) removeEventListener( Event.ENTER_FRAME, executeEvent );
		}
		
		public override function toString(): String
		{
			return "Application";
		}
	}
}